/**
 * 
 * Copyright (C) 2011 Cody Stoutenburg . All rights reserved.
 *
 *       This program is free software; you can redistribute it and/or
 *       modify it under the terms of the GNU Lesser General Public License
 *       as published by the Free Software Foundation; either version 2.1
 *       of the License, or (at your option) any later version.
 *
 *       This program is distributed in the hope that it will be useful,
 *       but WITHOUT ANY WARRANTY; without even the implied warranty of
 *       MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *       GNU Lesser General Public License for more details.
 *
 *       You should have received a copy of the GNU Lesser General Public License
 *       along with this program; if not, write to the Free Software
 *       Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA. 
 * 
 */
package ca.usherbrooke.behaviour.manual;

import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;

import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.JTextPane;
import javax.swing.Timer;

import ca.usherbrooke.agent.MyAgent;
import ca.usherbrooke.agent.controller.shared.IMessage;
import ca.usherbrooke.model.entity.IEntityModel;
import ca.usherbrooke.model.equipment.EquipmentModel;
import ca.usherbrooke.model.equipment.ProtectionModel;
import ca.usherbrooke.model.equipment.WeaponModel;
import ca.usherbrooke.model.world.IWorldModel;
import ca.usherbrooke.tools.position.Vector2D;

/**
 * @author Cody Stoutenburg
 * 
 */
public class ManualPlayerPanel extends JPanel implements ActionListener {
	private static final long serialVersionUID = 1L;

	private final MyAgent agent;

	private final JButton btnTakeObject;
	private final JButton btnDropObject;

	private final JButton btnAttack;

	private final JButton btnEquipWeapon;
	private final JButton btnUnequipWeapon;

	private final JButton btnEquipProtection;
	private final JButton btnUnequipProtection;

	private final JButton buttonUp;
	private final JButton buttonLeft;
	private final JButton buttonStop;
	private final JButton buttonRight;
	private final JButton buttonDown;
	private final JTextField textFieldMessage;
	private final JButton btnEnvoyerMessage;
	private final JTextPane textPane;
	private final JLabel lblMessagesRecu;

	/**
	 * Create the panel.
	 */
	public ManualPlayerPanel(MyAgent agent) {
		super();

		this.agent = agent;

		setPreferredSize(new Dimension(450, 259));
		setMaximumSize(new Dimension(400, 150));
		setMinimumSize(new Dimension(400, 150));
		GridBagLayout gridBagLayout = new GridBagLayout();
		gridBagLayout.columnWidths = new int[] { 0, 0, 0, 0, 0, 0, 16, 0, 0, 0,
				0, 0, 0 };
		gridBagLayout.rowHeights = new int[] { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
		gridBagLayout.columnWeights = new double[] { 0.0, 1.0, 0.0, 0.0, 0.0,
				0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, Double.MIN_VALUE };
		gridBagLayout.rowWeights = new double[] { 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
				1.0, 0.0, 0.0, Double.MIN_VALUE };
		setLayout(gridBagLayout);

		btnTakeObject = new JButton("Take Object");
		GridBagConstraints gbc_btnTakeObject = new GridBagConstraints();
		gbc_btnTakeObject.gridwidth = 3;
		gbc_btnTakeObject.insets = new Insets(0, 0, 5, 5);
		gbc_btnTakeObject.gridx = 1;
		gbc_btnTakeObject.gridy = 1;
		add(btnTakeObject, gbc_btnTakeObject);
		btnTakeObject.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				buttonTakeObject();
			}
		});

		buttonUp = new JButton("^");
		GridBagConstraints gbc_buttonUp = new GridBagConstraints();
		gbc_buttonUp.insets = new Insets(0, 0, 5, 5);
		gbc_buttonUp.gridx = 8;
		gbc_buttonUp.gridy = 1;
		add(buttonUp, gbc_buttonUp);
		buttonUp.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				buttonUp();
			}
		});

		btnDropObject = new JButton("Drop Object");
		GridBagConstraints gbc_btnDropObject = new GridBagConstraints();
		gbc_btnDropObject.gridwidth = 3;
		gbc_btnDropObject.insets = new Insets(0, 0, 5, 5);
		gbc_btnDropObject.gridx = 1;
		gbc_btnDropObject.gridy = 2;
		add(btnDropObject, gbc_btnDropObject);
		btnDropObject.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				buttonDropObject();
			}
		});

		buttonLeft = new JButton("<");
		GridBagConstraints gbc_buttonLeft = new GridBagConstraints();
		gbc_buttonLeft.insets = new Insets(0, 0, 5, 5);
		gbc_buttonLeft.gridx = 7;
		gbc_buttonLeft.gridy = 2;
		add(buttonLeft, gbc_buttonLeft);

		buttonLeft.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				buttonLeft();
			}
		});

		buttonStop = new JButton("||");
		GridBagConstraints gbc_buttonStop = new GridBagConstraints();
		gbc_buttonStop.insets = new Insets(0, 0, 5, 5);
		gbc_buttonStop.gridx = 8;
		gbc_buttonStop.gridy = 2;
		add(buttonStop, gbc_buttonStop);
		buttonStop.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				buttonStop();
			}
		});

		buttonRight = new JButton(">");
		GridBagConstraints gbc_buttonRight = new GridBagConstraints();
		gbc_buttonRight.insets = new Insets(0, 0, 5, 5);
		gbc_buttonRight.gridx = 9;
		gbc_buttonRight.gridy = 2;
		add(buttonRight, gbc_buttonRight);
		buttonRight.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				buttonRight();
			}
		});

		btnAttack = new JButton("Attack");
		GridBagConstraints gbc_btnAttack = new GridBagConstraints();
		gbc_btnAttack.gridwidth = 3;
		gbc_btnAttack.insets = new Insets(0, 0, 5, 5);
		gbc_btnAttack.gridx = 1;
		gbc_btnAttack.gridy = 3;
		add(btnAttack, gbc_btnAttack);
		btnAttack.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				buttonAttack();
			}
		});

		buttonDown = new JButton("v");
		GridBagConstraints gbc_buttonDown = new GridBagConstraints();
		gbc_buttonDown.insets = new Insets(0, 0, 5, 5);
		gbc_buttonDown.gridx = 8;
		gbc_buttonDown.gridy = 3;
		add(buttonDown, gbc_buttonDown);
		buttonDown.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				buttonDown();
			}
		});

		btnEquipWeapon = new JButton("Equip weapon");
		GridBagConstraints gbc_btnEquipWeapon = new GridBagConstraints();
		gbc_btnEquipWeapon.gridwidth = 3;
		gbc_btnEquipWeapon.insets = new Insets(0, 0, 5, 5);
		gbc_btnEquipWeapon.gridx = 1;
		gbc_btnEquipWeapon.gridy = 4;
		add(btnEquipWeapon, gbc_btnEquipWeapon);
		btnEquipWeapon.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				buttonTakeWeapon();
			}
		});

		btnUnequipWeapon = new JButton("Unequip weapon");
		GridBagConstraints gbc_btnUnequipWeapon = new GridBagConstraints();
		gbc_btnUnequipWeapon.gridwidth = 4;
		gbc_btnUnequipWeapon.insets = new Insets(0, 0, 5, 5);
		gbc_btnUnequipWeapon.gridx = 1;
		gbc_btnUnequipWeapon.gridy = 5;
		add(btnUnequipWeapon, gbc_btnUnequipWeapon);
		btnUnequipWeapon.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				buttonPutDownWeapon();
			}
		});

		lblMessagesRecu = new JLabel("Messages Recu:");
		GridBagConstraints gbc_lblMessagesRecu = new GridBagConstraints();
		gbc_lblMessagesRecu.gridwidth = 3;
		gbc_lblMessagesRecu.insets = new Insets(0, 0, 5, 5);
		gbc_lblMessagesRecu.gridx = 7;
		gbc_lblMessagesRecu.gridy = 5;
		add(lblMessagesRecu, gbc_lblMessagesRecu);

		btnEquipProtection = new JButton("Equip protection");
		GridBagConstraints gbc_btnEquipProtection = new GridBagConstraints();
		gbc_btnEquipProtection.gridwidth = 4;
		gbc_btnEquipProtection.insets = new Insets(0, 0, 5, 5);
		gbc_btnEquipProtection.gridx = 1;
		gbc_btnEquipProtection.gridy = 6;
		add(btnEquipProtection, gbc_btnEquipProtection);
		btnEquipProtection.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				buttonTakeProtection();
			}
		});

		textPane = new JTextPane();
		GridBagConstraints gbc_textPane = new GridBagConstraints();
		gbc_textPane.gridwidth = 4;
		gbc_textPane.gridheight = 2;
		gbc_textPane.insets = new Insets(0, 0, 5, 5);
		gbc_textPane.fill = GridBagConstraints.BOTH;
		gbc_textPane.gridx = 7;
		gbc_textPane.gridy = 6;
		add(textPane, gbc_textPane);

		btnUnequipProtection = new JButton("Unequip protection");
		GridBagConstraints gbc_btnUnequipProtection = new GridBagConstraints();
		gbc_btnUnequipProtection.gridwidth = 4;
		gbc_btnUnequipProtection.insets = new Insets(0, 0, 5, 5);
		gbc_btnUnequipProtection.gridx = 1;
		gbc_btnUnequipProtection.gridy = 7;
		add(btnUnequipProtection, gbc_btnUnequipProtection);
		btnUnequipProtection.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				buttonPutDownProtection();
			}
		});

		Timer t = new Timer(80, this);

		textFieldMessage = new JTextField();
		GridBagConstraints gbc_textField = new GridBagConstraints();
		gbc_textField.gridwidth = 3;
		gbc_textField.insets = new Insets(0, 0, 0, 5);
		gbc_textField.fill = GridBagConstraints.HORIZONTAL;
		gbc_textField.gridx = 1;
		gbc_textField.gridy = 8;
		add(textFieldMessage, gbc_textField);
		textFieldMessage.setColumns(10);

		btnEnvoyerMessage = new JButton("Envoyer");
		GridBagConstraints gbc_btnEnvoyerMessage = new GridBagConstraints();
		gbc_btnEnvoyerMessage.gridwidth = 2;
		gbc_btnEnvoyerMessage.insets = new Insets(0, 0, 0, 5);
		gbc_btnEnvoyerMessage.gridx = 4;
		gbc_btnEnvoyerMessage.gridy = 8;
		add(btnEnvoyerMessage, gbc_btnEnvoyerMessage);
		t.start();
		btnEnvoyerMessage.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				buttonSendMessage();
			}
		});
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		if (agent.getWorld() != null && agent.getEntity() != null) {
			refresh();
		}
	}

	public void refresh() {
		IWorldModel world = agent.getWorld();
		IEntityModel entity = agent.getEntity();

		IMessage msg = agent.popMessage();
		if (msg != null) {
			IWorldModel w = (IWorldModel) msg.getObject();
			textPane.setText(msg.getGuidSender() + ": " + msg.getMessage()
					+ "\n vision: " + w.getSize());

		}

		btnAttack.setEnabled(true);
		btnDropObject.setEnabled(true);
		btnEquipProtection.setEnabled(true);
		btnUnequipProtection.setEnabled(true);
		btnEquipWeapon.setEnabled(true);
		btnUnequipWeapon.setEnabled(true);

		if (entity.getEquipments().isEmpty()) {
			// si il n'y a pas d'equipement
			btnDropObject.setEnabled(false);
			btnEquipProtection.setEnabled(false);
			btnEquipWeapon.setEnabled(false);
		} else {
			// si il y a des equipements
			if (entity.getProtectionsInEquipments().isEmpty()) {
				btnEquipProtection.setEnabled(false);
			}
			if (entity.getWeaponsInEquipments().isEmpty()
					|| entity.getCurrentWeapon() != null) {
				btnEquipWeapon.setEnabled(false);
			}
		}

		if (entity.getCurrentProtection().isEmpty()) {
			btnUnequipProtection.setEnabled(false);
		}
		if (entity.getCurrentWeapon() == null) {
			btnUnequipWeapon.setEnabled(false);
		}

		if (world.getAllEquipments().isEmpty()) {
			btnTakeObject.setEnabled(false);
		}
		if (world.getAllEntities().size() <= 1) {
			btnAttack.setEnabled(false);
		}
	}

	private void buttonLeft() {
		Vector2D speed = new Vector2D(-10.0f, 0.0f);
		agent.setSpeed(speed);
	}

	private void buttonRight() {
		Vector2D speed = new Vector2D(10.0f, 0.0f);
		agent.setSpeed(speed);
	}

	private void buttonUp() {
		Vector2D speed = new Vector2D(0.0f, -10.0f);
		agent.setSpeed(speed);

	}

	private void buttonDown() {
		Vector2D speed = new Vector2D(0.0f, 10.0f);
		agent.setSpeed(speed);
	}

	private void buttonStop() {
		Vector2D speed = new Vector2D(0.0f, 0.0f);
		agent.setSpeed(speed);
	}

	private void buttonTakeObject() {
		List<EquipmentModel> equipments = this.agent.getWorld().getEquipment(
				this.agent.getEntity().getSize());

		if (!equipments.isEmpty()) {
			agent.grabObject(equipments.get(0).getGuid());
		}
	}

	private void buttonDropObject() {
		List<EquipmentModel> equipments = this.agent.getEntity()
				.getEquipments();
		if (!equipments.isEmpty()) {
			agent.dropObject(equipments.get(0).getGuid());
		}
	}

	private void buttonAttack() {
		List<IEntityModel> entities = this.agent.getWorld().getAllEntities();
		entities.remove(this.agent.getEntity());
		if (!entities.isEmpty()) {
			agent.attack(entities.get(0).getGuid());
		}
	}

	private void buttonTakeWeapon() {
		List<WeaponModel> allWeapons = agent.getEntity()
				.getWeaponsInEquipments();
		if (!allWeapons.isEmpty()) {
			agent.takeWeapon(allWeapons.get(0).getGuid());
		}
	}

	private void buttonTakeProtection() {
		List<ProtectionModel> allProtectionModels = agent.getEntity()
				.getProtectionsInEquipments();
		if (!allProtectionModels.isEmpty()) {
			agent.takeProtection(allProtectionModels.get(0).getGuid());
		}
	}

	private void buttonPutDownWeapon() {
		WeaponModel weapons = agent.getEntity().getCurrentWeapon();
		if (weapons != null) {
			agent.putDownWeapon();
		}
	}

	private void buttonPutDownProtection() {
		List<ProtectionModel> allProtection = agent.getEntity()
				.getCurrentProtection();
		if (!allProtection.isEmpty()) {
			agent.putDownProtection(allProtection.get(0).getGuid());
		}
	}

	private void buttonSendMessage() {
		List<IEntityModel> allEntities = agent.getWorld().getAllEntities();
		if (!allEntities.isEmpty()) {
			agent.sendMessage(allEntities.get(0).getGuid(),
					new IMessage(agent.getEntity().getGuid(), "new Message",
							this.agent.getWorld(), textFieldMessage.getText()));
			textFieldMessage.setText("");
		}
	}
}
